﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace Razre.Base
{
    /// <summary>
    /// Base Object that provides property changed notification handlers and validation for inherited objects
    /// </summary>
    public class BaseNotificationObject : INotifyPropertyChanged, IDataErrorInfo
    {
        #region ctors

        /// <summary>
        /// Default Constructor
        /// </summary>
        public BaseNotificationObject()
        {
            //default the delimiter to a carriage return line feed
            ErrorMessageDelimiter = "\r\n";
        }

        #endregion

        #region INotifyPropertyChanged Members

        /// <summary>
        /// Event that is executed whena property changes
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Method Invokes the PropertyChanged event for a given Property 
        /// </summary>
        /// <param name="propertyName">The name of the property to notify</param>
        public virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        #region IDataErrorInfo Members

        public string Error
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// Indexer property handled by IDataErrorInfo
        /// </summary>
        /// <param name="columnName">Property name to be validated</param>
        /// <returns>Error Message as a result of the validation</returns>
        public string this[string columnName]
        {
            get 
            {
                //Create Validation arguments and execute the PropertyValidated Handler
                ValidateEventArgs args = new ValidateEventArgs();
                args.PropertyName = columnName;
                ValidateProperty(args);

                //if the property is Valid
                if (args.IsValid)
                {
                    return string.Empty;
                }
                else
                {
                    //return a formatted string based on the error messages and the set delimiter
                    return string.Join(ErrorMessageDelimiter, args.ErrorMessages.ToArray());
                }
            }
        }

        /// <summary>
        /// Virtual method that occurs when a property is validated
        /// </summary>
        /// <param name="args">Validation arguments to be modified to determine the validation rules</param>
        protected virtual void ValidateProperty(ValidateEventArgs args)
        {
            //If the event is handled
            if (OnPropertyValidated != null)
            {
                //execute it passing in the arguments
                OnPropertyValidated(this, args);
            }
        }

        /// <summary>
        /// Event to notify that a property has been validated
        /// </summary>
        public event EventHandler<ValidateEventArgs> OnPropertyValidated;

        /// <summary>
        /// Property defining the delimiter to be used when formatting the validation message
        /// </summary>
        public string ErrorMessageDelimiter { get; set; }

        #endregion
    }
}
